package cn.com.joycode.nimble.admin.security.authentication;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Component
public class NimbleAdminAuthenticationProvider implements AuthenticationProvider {

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.isAssignableFrom(NimbleAdminAuthenticationToken.class);
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        log.info("调用认证方法");
        // 转换为token
        NimbleAdminAuthenticationToken token = (NimbleAdminAuthenticationToken) authentication;
        // 认证明细
        NimbleAdminAuthenticationDetails details = new NimbleAdminAuthenticationDetails();
        token.setDetails(details);
        token.setAuthenticated(true);
        // 返回非空则认证成功
        String jwt = JWT.create()
                .withClaim("user_id", "maxwoods")
                .withClaim("user_name", "joycode")
                .withIssuedAt(new Date())
                .withExpiresAt(DateUtil.offset(new Date(), DateField.MINUTE, 30))
                .sign(Algorithm.HMAC256("joycode"));
        log.info("用户证成功:{}", jwt);
        String userName = JWT.decode(jwt).getClaim("user_name").asString();

        JWTVerifier jwtv = JWT.require(Algorithm.HMAC256("joycode")).withClaim("user_name", "joycode").build();
        DecodedJWT djwt = jwtv.verify(jwt);

        log.info("认证用户为:{}", userName);
        GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("master");
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        grantedAuthorities.add(grantedAuthority);
        token = new NimbleAdminAuthenticationToken(grantedAuthorities);
        return token;
    }
}
